package com.bzkj.basicinfo.utils;

import com.bzkj.basicinfo.domain.basic.BasicStoUnit;
import com.bzkj.basicinfo.domain.basic.vo.TableXXXSkuVo1;
import com.bzkj.basicinfo.domain.ncc.TableXXXSku;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @Date 2024/12/23 13:51:53
 * @description 生成二维码
 */
@Component
public class GenerateQRCodeUtils
{
    /**
     * 生成商品加密后的二维码字符串 Base64字符串二维码
     *
     * @param pkMarbasclass
     * @return base64 编码后的字符串
     * @throws IOException
     */
    public List<TableXXXSkuVo1> crateQRCode(List<TableXXXSku> list, String pkMarbasclass,String vbatchCode)
    {
        QRCodeWriter writer = new QRCodeWriter();
        @SuppressWarnings("rawtypes") Map<EncodeHintType, Comparable> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
        hints.put(EncodeHintType.MARGIN, 0);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        List<TableXXXSkuVo1> vos = list.parallelStream().map(sku -> {
            try {
                TableXXXSkuVo1 temp = new TableXXXSkuVo1();
                //复验期为空时显示空
                StringBuilder sb = new StringBuilder();
                sb.append("(ID)" + pkMarbasclass);
                // + "(BN)" + vbatchCode + "(EXP)" + expDate + "(SN)" + sku.getSkuBarId();
                if (StringUtils.isNoneBlank(vbatchCode)) {
                    sb.append("(BN)" + vbatchCode);
                }
//                if (Objects.nonNull(sku.getPeriodValidity()) && Objects.isNull(sku.getResetDate())) {
//                    String exp = format.format(sku.getPeriodValidity());
//                    if(StringUtils.isNoneBlank(exp)){
//                        sb.append("(EXP)" + exp);
//                    }
//                }
                if (StringUtils.isNoneBlank(sku.getSkuBarId())) {
                    sb.append("(SN)" + sku.getSkuBarId());
                }
                BitMatrix bitMatrix = writer.encode(sb.toString(), BarcodeFormat.QR_CODE, 80, 80, hints);

                BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);

                ByteArrayOutputStream os = new ByteArrayOutputStream();
                ImageIO.write(bufferedImage, "png", os);
                sku.setQRCode("data:image/png;base64," + Base64.getEncoder().encodeToString(os.toByteArray()));
//                BeanUtils.copyProperties(sku, temp);
                temp.setQRCode("data:image/png;base64," + Base64.getEncoder().encodeToString(os.toByteArray()));
                temp.setSkuBarId(sku.getSkuBarId());
                temp.setSortNum(sku.getSortNum());
                temp.setGubflag(sku.getGubflag());
                temp.setDef2(sku.getDef2());
                return temp;
            } catch(Exception e) {
                throw new RuntimeException(e);
            }
        }).collect(Collectors.toList());
        return vos;
    }

    /**
     * 生成商品加密后的二维码字符串 Base64字符串二维码
     *
     * @param pkMarbasclass
     * @return base64 编码后的字符串
     * @throws IOException
     */
    public void crateQRCode(TableXXXSku temp, String pkMarbasclass)
    {
        QRCodeWriter writer = new QRCodeWriter();
        @SuppressWarnings("rawtypes") Map<EncodeHintType, Comparable> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
        hints.put(EncodeHintType.MARGIN, 2);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        try {

            StringBuilder sb = new StringBuilder();
            sb.append("(ID)" + pkMarbasclass);
            // + "(BN)" + vbatchCode + "(EXP)" + expDate + "(SN)" + sku.getSkuBarId();
            //批号 复验期 序列号为空时不显示

            if (StringUtils.isNotBlank(temp.getVbatchCode())) {
                sb.append("(BN)" + temp.getVbatchCode());
            }
//            if (Objects.nonNull(temp.getPeriodValidity()) && Objects.isNull(temp.getResetDate())) {
//                String exp = format.format(temp.getPeriodValidity());
//                if (StringUtils.isNotBlank(exp)) {
//                    sb.append("(EXP)" + exp);
//                }
//            }
            if (StringUtils.isNotBlank(temp.getSkuBarId())) {
                sb.append("(SN)" + temp.getSkuBarId());
            }

            BitMatrix bitMatrix = writer.encode(sb.toString(), BarcodeFormat.QR_CODE, 80, 80, hints);

            BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);

            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, "png", os);
            temp.setQRCode("data:image/png;base64," + Base64.getEncoder().encodeToString(os.toByteArray()));
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 生成货位加密后的二维码字符串 Base64字符串二维码
     *
     * @return base64 编码后的字符串
     * @throws IOException
     */
    public void crateQRCode(List<BasicStoUnit> list)
    {
        QRCodeWriter writer = new QRCodeWriter();
        @SuppressWarnings("rawtypes") Map<EncodeHintType, Comparable> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
        hints.put(EncodeHintType.MARGIN, 2);
        list.parallelStream().forEach(item -> {
            try {
                String content = item.getStoUnitCode();

                BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, 80, 80, hints);

                BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);

                ByteArrayOutputStream os = new ByteArrayOutputStream();
                ImageIO.write(bufferedImage, "png", os);
                item.setQRCode("data:image/png;base64," + Base64.getEncoder().encodeToString(os.toByteArray()));
            } catch(Exception e) {
                throw new RuntimeException(e);
            }
        });
    }

    public List<BasicStoUnit> crateQRCodeString(List<String> list)
    {
        List<BasicStoUnit> list1 = new ArrayList<>();
        QRCodeWriter writer = new QRCodeWriter();
        @SuppressWarnings("rawtypes") Map<EncodeHintType, Comparable> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
        hints.put(EncodeHintType.MARGIN, 2);
        list.parallelStream().forEach(item -> {
            try {
                BitMatrix bitMatrix = writer.encode(item, BarcodeFormat.QR_CODE, 80, 80, hints);

                BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);

                ByteArrayOutputStream os = new ByteArrayOutputStream();
                ImageIO.write(bufferedImage, "png", os);
                BasicStoUnit unit = new BasicStoUnit();
                unit.setStoUnitCode(item);
                unit.setQRCode("data:image/png;base64," + Base64.getEncoder().encodeToString(os.toByteArray()));
                list1.add(unit);
            } catch(Exception e) {
                throw new RuntimeException(e);
            }
        });
        return list1;
    }

    public void crateQRCodeMap(List<Map<String, Object>> list, String pkMarbasclass)
    {
        QRCodeWriter writer = new QRCodeWriter();
        @SuppressWarnings("rawtypes") Map<EncodeHintType, Comparable> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
        hints.put(EncodeHintType.MARGIN, 2);
        SimpleDateFormat format = new SimpleDateFormat("yyMMdd");
        SimpleDateFormat formatTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        list.parallelStream().forEach(sku -> {
            try {
                String format1 = format.format(sku.get("period_validity"));
                String format2 = formatTime.format(sku.get("dbizdate"));
                sku.put("period_validity", format1);
                sku.put("dbizdate", format2);
                String content = "(ID)" + pkMarbasclass + "(BN)" + sku.get("pk_batchcode1") + "(EXP)" + format1 + "(SN)" + sku.get("sku_bar_id");

                BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, 80, 80, hints);

                BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);

                ByteArrayOutputStream os = new ByteArrayOutputStream();
                ImageIO.write(bufferedImage, "png", os);
                sku.put("qrCode", "data:image/png;base64," + Base64.getEncoder().encodeToString(os.toByteArray()));
            } catch(Exception e) {
                throw new RuntimeException(e);
            }
        });
    }

    /**
     * 给前端产生一个条形码
     *
     * @param number 编码
     * @param width  宽度
     * @param height 高度
     */
    public  static String createBarCode(String number, Integer width, Integer height) {
        // 生成条形码
        BufferedImage image = getBarCode(number, width, height);
        // 使用流的方式
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            ImageIO.write(image, "png", out);
        } catch (Exception e) {
            // log.error("generate code error! error message:{}", "出现问题！");
            e.printStackTrace();
        }
        // 将流转成数组
        byte[] bytes = out.toByteArray();
        BASE64Encoder encoder = new BASE64Encoder();
        // 把生成的编码返回去
        return "data:image/png;base64," + encoder.encodeBuffer(bytes).trim();
    }

    /**
     * 产生条形码的方法
     *
     * @param number 编码
     * @param width  宽度
     * @param height 高度
     */
    public static BufferedImage getBarCode(String number, Integer width, Integer height) {
        try {
            BitMatrix bitMatrix = new MultiFormatWriter().encode(number, BarcodeFormat.CODE_128, width, height);
            return MatrixToImageWriter.toBufferedImage(bitMatrix);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
